package br.com.intelsys.basics.itag;

import java.io.Serializable;

/**
 * Representa a pagina que esta sendo iterada enquanto esta sendo exibida no
 * JSP.<br/>
 * <br/>
 * 
 * Usado pela tag:<br/>
 * <br/>
 * &lt;%@ taglib prefix="cp" tagdir="/WEB-INF/tags/cpage" %&rt;<br/>
 * <br/>
 * 
 * A instancia desta classe eh obtida a partir da variavel definida no atributo
 * "var" da tag &lt;cp:index&rt;
 * 
 * @author Patrick Givisiez
 * 
 */

public final class IPage implements Serializable {
	private static final long serialVersionUID = 1L;
	private int number;
	private int page;
	private int total;
	private int perPage;
	private int size;
	private boolean firstBlock;
	private boolean lastBlock;
	private boolean firstFromBlock;
	private boolean lastFromBlock;
	private Boolean hasMore;

	/**
	 * Retorna o numero da pagina atual
	 * 
	 * @return Numero da pagina atual
	 */
	public int getNumber() {
		return (number);
	}

	/**
	 * Retorna o nome da pagina atual
	 * 
	 * @return Nome da pagina atual
	 */
	public int getLabel() {
		return (number + 1);
	}

	/**
	 * Retorna o numero da pagina selecionada
	 * 
	 * @return Numero da pagina selecionada
	 */
	public int getPage() {
		return (page);
	}

	/**
	 * Retorna o total de registros na lista
	 * 
	 * @return Total de registros na lista
	 */
	public int getTotal() {
		return (total);
	}

	/**
	 * Retorna o total de registros por pagina
	 * 
	 * @return Total de registros por pagina
	 */
	public int getPerPage() {
		return (perPage);
	}

	/**
	 * Retorna o tamanho total de paginas que serao exibidas de uma vez
	 * 
	 * @return Tamanho total de paginas que serao exibidas de uma vez
	 */
	public int getSize() {
		return (size);
	}

	/**
	 * Verifica se eh o primeiro bloco que esta sendo exibido
	 * 
	 * @return true se for o primeiro
	 */
	public boolean isFirstBlock() {
		return (firstBlock);
	}

	/**
	 * Verifica se eh o ultimo bloco que esta sendo exibido
	 * 
	 * @return true se for o ultimo
	 */
	public boolean isLastBlock() {
		return (lastBlock);
	}

	/**
	 * Verifica se esta eh a primeira pagina da lista
	 * 
	 * @return true se for o primeiro
	 */
	public boolean isFirstPage() {
		return (page == 0);
	}

	/**
	 * Verifica se esta eh a ultima pagina da lista
	 * 
	 * @return true se for o ultimo
	 */
	public boolean isLastPage() {
		if (hasMore != null) {
			return !hasMore;
		}
		return (page == (getMaxPage() - 1));
	}

	/**
	 * Verifica se este eh o primeiro item do bloco exibido
	 * 
	 * @return true se for o primeiro
	 */
	public boolean isFirstFromBlock() {
		return (firstFromBlock);
	}

	/**
	 * Verifica se este eh o ultimo item do bloco exibido
	 * 
	 * @return true se for o ultimo
	 */
	public boolean isLastFromBlock() {
		return (lastFromBlock);
	}

	/**
	 * Verifica se esta eh a pagina que esta atualmente selecionada
	 * 
	 * @return true se for a pagina selecionada
	 */
	public boolean isCurrent() {
		return (page == number);
	}

	/**
	 * Pega o numero da pagina para mudanca do bloco anterior.<br/>
	 * </br> Usado para mudanca de blocos.
	 * 
	 * @return Numero da pagina atual menos o total de paginas existente em um
	 *         bloco
	 */
	public int getLastBlockPageNumber() {
		int pageTmp = page - size;
		if (pageTmp < 0) {
			pageTmp = 0;
		}
		return (pageTmp);
	}

	/**
	 * Pega o numero da pagina para mudanca do proximobloco.<br/>
	 * </br> Usado para mudanca de blocos.
	 * 
	 * @return Numero da pagina atual mais o total de paginas existente em um
	 *         bloco
	 */
	public int getNextBlockPageNumber() {
		int pageTmp = page + size;
		int maxPage = getMaxPage() - 1;
		if (pageTmp > maxPage) {
			pageTmp = maxPage;
		}
		return (pageTmp);
	}

	/**
	 * Pega o numero da pagina anterior a atual.<br/>
	 * <br/>
	 * Usado para mudanca de paginas.
	 * 
	 * @return Numero da pagina atual menos um.
	 */
	public int getLastPageNumber() {
		int pageTmp = page - 1;
		if (pageTmp < 0) {
			pageTmp = 0;
		}
		return (pageTmp);
	}

	public int getLastPageLabel() {
		return getLastPageNumber() + 1;
	}

	/**
	 * Pega o numero da pagina posterior a atual.<br/>
	 * <br/>
	 * Usado para mudanca de paginas.
	 * 
	 * @return Numero da pagina atual mais um.
	 */
	public int getNextPageNumber() {
		int pageTmp = page + 1;
		int maxPage = getMaxPage() - 1;
		if (hasMore != null && hasMore) {
			return pageTmp;
		} else if (hasMore != null && !hasMore) {
			return page;
		}
		if (pageTmp > maxPage) {
			pageTmp = maxPage;
		}
		return (pageTmp);
	}

	public int getNextPageLabel() {
		return getNextPageNumber() + 1;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setPerPage(int perPage) {
		this.perPage = perPage;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public void setFirstBlock(boolean firstBlock) {
		this.firstBlock = firstBlock;
	}

	public void setLastBlock(boolean lastBlock) {
		this.lastBlock = lastBlock;
	}

	public void setFirstFromBlock(boolean firstFromBlock) {
		this.firstFromBlock = firstFromBlock;
	}

	public void setLastFromBlock(boolean lastFromBlock) {
		this.lastFromBlock = lastFromBlock;
	}

	public void setHasMore(Boolean hasMore) {
		this.hasMore = hasMore;
	}

	private int getMaxPage() {
		return ((int) Math.ceil((double) total / perPage));
	}

}